package com.linkhub.oms.component.excel.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.google.common.collect.Lists;
import com.linkhub.oms.common.constant.FileConstant;
import com.linkhub.oms.common.exception.BizException;
import com.linkhub.oms.component.excel.listener.BaseDataListener;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Description: EasyExcelUtil
 * @Author: echo
 * @Date: 2024/5/4 18:36
 * @Version: 1.0
 */
@Slf4j
public class EasyExcelUtil {

    @SneakyThrows
    public static <T> List<T> read(MultipartFile multipartFile,
                                   Class<T> clazz,
                                   BaseDataListener<T> readListener) {
        checkImportFile(multipartFile);
        return read(multipartFile.getInputStream(), clazz, readListener);

    }

    @SneakyThrows
    public static <T> List<T> read(InputStream inputStream,
                                   Class<T> clazz,
                                   BaseDataListener<T> readListener) {

        EasyExcel.read(inputStream, clazz, readListener)
                .ignoreEmptyRow(true)
                .headRowNumber(1)
                .autoTrim(true)
                .sheet()
                .doRead();

        return readListener.acquireDataList();

    }

    @SneakyThrows
    public static <T> void exportExcelTemplate(HttpServletResponse response,
                                               String fileName,
                                               Class<T> clazz) {
        setResponseHeader(response, fileName);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
        // 写入流
        try (ServletOutputStream os = response.getOutputStream()) {

            EasyExcel.write(os, clazz)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .sheet("template")
                    .doWrite(Lists.newArrayListWithCapacity(0));

        } catch (IOException e) {
            log.error("exportExcelTemplate error", e);
            throw new BizException("exportExcelTemplate error");
        }

    }

    private static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        // 表头单元格居中
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //表头背景色-灰色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
        //表头字体--黑色加粗字号12
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints(Short.parseShort("12"));
        headWriteFont.setBold(true);
        headWriteFont.setColor(IndexedColors.BLACK.getIndex());
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 表格单元格居左
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    private static void setResponseHeader(HttpServletResponse response, String fileName) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
//        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    }

    private static String checkImportFile(MultipartFile excelFile) {
        if (excelFile.isEmpty()) {
            throw new BizException("excelFile.empty.error");
        }
        //校验文件
        String originalFilename = excelFile.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            throw new BizException("excelFile.originalFilename.empty.error");
        }
        // 校验文件后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(StringPool.DOT) + 1);
        if (!FileConstant.SUFFIX_BOND_IMPORT_FILE_LIST.contains(suffix)) {
            throw new BizException("excelFile.type.error");
        }
        // 校验文件大小
        if (excelFile.getSize() > FileConstant.BYTE_50_MB) {
            throw new BizException("excelFile.size.error");
        }
        return suffix;
    }

    public static boolean isValidFile(MultipartFile excelFile) {
        if (excelFile.isEmpty()) {
            throw new BizException("excelFile.empty.error");
        }
        //校验文件
        String originalFilename = excelFile.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            throw new BizException("excelFile.originalFilename.empty.error");
        }
        // 校验文件后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(StringPool.DOT) + 1);
        if (!FileConstant.SUFFIX_BOND_IMPORT_FILE_LIST.contains(suffix)) {
            throw new BizException("excelFile.type.error");
        }
        return true;
    }
}
